#include "ManejadorVotante.h"

using namespace Manejadores;

ManejadorVotante::ManejadorVotante() {
	Configuracion* config = Configuracion::getInstancia();
	string pathDeDatos = config->getNombreArchivoVotante();
	this->votantes = new ArchivoDeEstructurasVariables(pathDeDatos);
	this->indicePorDNI = new HashExtensible("IndicePorUnicidadDNIVotante");

	this->ultimaPosicionLeida = 0;
}

bool ManejadorVotante::alta(Votante* votante) {
	string claveDNI = Utils::convertirEnteroAString(votante->getDNI());

	if (!indicePorDNI->existe(claveDNI)) {
		unsigned int posicionDelRegistro = votantes->insertar(votante);
		indicePorDNI->insertar(claveDNI, posicionDelRegistro);

		this->indicePorDNI->exportarTxt("IndicePorUnicidadDNIVotante");
		return true;
	} else {
		return false;
	}
}

bool ManejadorVotante::baja(Votante* votante) {

	string claveDNI = Utils::convertirEnteroAString(votante->getDNI());
	IRegistroIndice* aBorrar = indicePorDNI->buscar(claveDNI);

	if (aBorrar->getOffsets()->size() > 0) {
		votantes->borrar(votante, aBorrar->getOffsets()->at(0));
		indicePorDNI->eliminar(claveDNI, aBorrar->getOffsets()->at(0));
		delete aBorrar;

		this->indicePorDNI->exportarTxt("IndicePorUnicidadDNIVotante");
		return true;
	} else
		return false;
}

bool ManejadorVotante::modificacion(Votante* votante) {
	string claveDNI = Utils::convertirEnteroAString(votante->getDNI());
	IRegistroIndice* viejaPosicion = indicePorDNI->buscar(claveDNI);
	unsigned int nuevaPosicion = votantes->modificar(votante, viejaPosicion->getOffsets()->at(0));
	if (viejaPosicion->getOffsets()->at(0) != nuevaPosicion) {
		indicePorDNI->modificar(claveDNI, viejaPosicion->getOffsets()->at(0), nuevaPosicion);
		delete viejaPosicion;
		return true;
	} else
		return false;
}

Votante* ManejadorVotante::recuperar(string claveVotante) {

	IRegistroIndice* registro = this->indicePorDNI->buscar(claveVotante);
	if (registro->getOffsets()->size() > 0) {
		Votante* votante = new Votante();
		this->votantes->leer(votante, registro->getOffsets()->at(0));
		delete registro;
		return votante;
	} else {
		delete registro;
		return NULL;
	}

}

/* Recupera el offset de todos los votantes del indice de unicidad */
vector<Votante*>* ManejadorVotante::recuperarVotantes(unsigned int numeroDeVotantes) {

	vector<Votante*>* votantes = new vector<Votante*> ();
	vector<unsigned int>* offsets = this->indicePorDNI->getTodosLosDatos();

	for (unsigned int i = 0; i < offsets->size(); i++) {

		if (numeroDeVotantes != 0) {
			if (i + 1 > numeroDeVotantes)
				break;
		}
		Votante* nuevoVotante = new Votante();
		this->votantes->leer(nuevoVotante, offsets->at(i));

		if (nuevoVotante->getDNI() > 0)
			votantes->push_back(nuevoVotante);
		else
			delete nuevoVotante;
	}

	delete offsets;
	return votantes;
}

bool ManejadorVotante::existe(string dniVotante) {

	return this->indicePorDNI->existe(dniVotante);
}

bool ManejadorVotante::listarTodos(){
	bool toReturn = false;
	fstream txtFile;
	Configuracion* config = Configuracion::getInstancia();
	string path = config->getPathReportes() + "ListadoVotantes.txt";
	txtFile.open(path.c_str(), ios::out);
	if (txtFile.bad()) {
		txtFile.open(path.c_str(), ios::out);
	}
	txtFile << "DNI		Nombre y Apellido " << endl;
	txtFile << "===================================" << endl;

	vector<unsigned int>* offsets = this->indicePorDNI->getTodosLosDatos();
	if(!offsets->empty()){
		Votante* votante = new Votante();
		for (unsigned int i = 0; i < offsets->size(); ++i) {
			this->votantes->leer(votante, offsets->at(i));
			txtFile << votante->getDNI() << "	" << votante->getNombreYApellido() << endl;
		}
		delete votante;
		toReturn = true;
		}else{
			toReturn = false;
		}
		txtFile.close();
		return toReturn;
}

ManejadorVotante::~ManejadorVotante() {
	delete this->votantes;
	delete this->indicePorDNI;
}
